#coding=utf-8

import os
import importlib

from tornado.log import access_log as logger
from .const import SERVICE_DIR
from orm.model import build_model,Model


"""
    扫描传入进来的路径下的所有 filter 模块
        filter 函数 存储在 array里, 执行顺序为加载顺序, 即 filter 文件中的位置
        多个 filter 文件, 如何处理加载顺序 ? 因此应该考虑设定 level字段来控制

    扫描传入进来的路径下的所有 controller 模块

"""


__controllerStore={}
__filterStroe=[]


def mapping(uri, bypass=False,filters=None):
    def func_wrapper(func):
        if __controllerStore.get(uri):
            raise Exception("Uri=%s has bean mapped" % uri)

        logger.info("    |-- mapping: %s --> %s", uri, func.__name__)
        filter_funcs = []
        if isinstance(filters,(str,unicode)):
            filter_funcs.append(FilterManager.get_filter(filters))
        elif isinstance(filters,(tuple,list)):
            for each in filters:
                filter_funcs.append(FilterManager.get_filter(each))
        __controllerStore[uri] = (func,bypass,tuple(filter_funcs))
        return func
    return func_wrapper


def calling(uri):
    return __controllerStore.get(uri, (None,None,None))


class FilterManager:
    __filter_store = {}
    __global_filters = []

    @staticmethod
    def register(name,global_=False):
        def func_wrapper(func):
            FilterManager.__filter_store[name] = func
            logger.info("    |-- filtering: %s", func.__name__)
            if global_:
                FilterManager.__global_filters.append(func)
            return func
        return func_wrapper

    @staticmethod
    def get_filter(name):
        return FilterManager.__filter_store[name]

    @staticmethod
    def get_global_filters():
        return FilterManager.__global_filters


def filtering():
    def func_wrapper(func):
        __filterStroe.append(func)
        logger.warn("    |-- filtering: %s", func.__name__)

        return func
    return func_wrapper


def getFilters():
    return __filterStroe


class Scanner:
    def __init__(self):
        pass


    @staticmethod
    def scaningFilter(filterDir):
        logger.info("Begin Scan all filter...")
        Scanner.scaningMoudel(filterDir)


    @staticmethod
    def scaningCtrller(ctrllerDir):
        logger.info("Begin Scan all controller...")
        Scanner.scaningMoudel(ctrllerDir)

    @staticmethod
    def scaningMoudel(pkgPath):
        if pkgPath.endswith("/"):
            newPath = pkgPath.replace("/", "")
        else:
            newPath = pkgPath.replace("/", ".")

        names=os.listdir(pkgPath)
        for name in names:
            if name.startswith("__init__.py") or not name.endswith(".py"):
                continue

            fileName = name.split(".")[0]
            moduleTmp = "%s.%s" % (newPath, fileName)
            logger.info("  |-- load: %s", moduleTmp)

            importlib.import_module(moduleTmp)

    @staticmethod
    def scan_service():
        logger.info("Begin build all service model...")
        serivce_path = os.path.join(os.getcwd(), SERVICE_DIR)
        all_services = [n.split(os.path.sep)[-1] for n in os.listdir(serivce_path) if not n.startswith('_')
                        and os.path.isdir(os.path.sep.join([serivce_path,n]))]
        all_service_modol =[]
        for n in all_services:
            try:
                all_service_modol.append(importlib.import_module('.'.join([SERVICE_DIR, n, 'model'])))
            except:
                pass
        for index, serivce_model in enumerate(all_service_modol):
            for obj_name in dir(serivce_model):
                if obj_name.startswith('_'):
                    continue
                obj = getattr(serivce_model, obj_name)
                if hasattr(obj, '__base__') and obj not in [Model] and issubclass(obj, Model):
                    # 在这里引入model的载入
                    build_model(obj)
                    logger.info("  |-- build: %s:%s" % (serivce_model.__name__, obj.__name__))

